home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / kernel / rpc / rpcDebug.c < prev    next >
C/C++ Source or Header  |  1992-12-18  |  12KB  |  453 lines

  1. /*
  2.  * rpcDebug.c --
  3.  *
  4.  *    Debugging routines for the Rpc system.  These routines are used
  5.  *    to profile and trace the whole system.
  6.  *
  7.  * Copyright 1985 Regents of the University of California
  8.  * All rights reserved.
  9.  */
  10.  
  11. #ifndef lint
  12. static char rcsid[] = "$Header: /cdrom/src/kernel/Cvsroot/kernel/rpc/rpcDebug.c,v 9.9 92/08/10 22:59:01 mgbaker Exp $ SPRITE (Berkeley)";
  13. #endif /* not lint */
  14.  
  15. #include <sprite.h>
  16. #include <stdio.h>
  17. #include <status.h>
  18. #include <rpc.h>
  19. #include <rpcInt.h>
  20. #include <fs.h>
  21. #include <timer.h>
  22. #include <vm.h>
  23. #include <sync.h>
  24. #include <sched.h>
  25. #include <rpcClient.h>
  26. #include <rpcServer.h>
  27. #include <rpcTrace.h>
  28. #include <dev.h>
  29. #include <user/sysStats.h>
  30.  
  31. #include <fsio.h>
  32. #include <fsrecov.h>
  33. #include <recov.h>
  34.  
  35.  
  36.  
  37. /*
  38.  *----------------------------------------------------------------------
  39.  *
  40.  * Test_RpcStub --
  41.  *
  42.  *    System call stub for the Rpc testing hook.  This is used
  43.  *    to do ECHO and SEND rpcs.
  44.  *
  45.  * Results:
  46.  *    An error code from the RPC.
  47.  *
  48.  * Side effects:
  49.  *    None.
  50.  *
  51.  *----------------------------------------------------------------------
  52.  */
  53.  
  54. ReturnStatus
  55. Test_RpcStub(command, argPtr)
  56.     int command;
  57.     Address argPtr;
  58. {
  59.     int inSize;
  60.     int outSize;
  61.     int argSize;
  62.     ReturnStatus status = SUCCESS;
  63.     
  64.     switch(command) {
  65.     case TEST_RPC_ECHO: {
  66.         Rpc_EchoArgs *echoArgsPtr = (Rpc_EchoArgs *)argPtr;
  67.         Time deltaTime;
  68.  
  69.         /*
  70.          * Make Accessible the struct containing the Echo arguments,
  71.          * then the in and out buffers.
  72.          */
  73.         Vm_MakeAccessible(VM_READONLY_ACCESS, sizeof(Rpc_EchoArgs),
  74.                (Address) echoArgsPtr, &argSize,
  75.                (Address *) (&echoArgsPtr));
  76.         if (echoArgsPtr == (Rpc_EchoArgs *)NIL) {
  77.         return(RPC_INVALID_ARG);
  78.         }
  79.         Vm_MakeAccessible(VM_READONLY_ACCESS,
  80.                   echoArgsPtr->size, echoArgsPtr->inDataPtr,
  81.                   &inSize, &echoArgsPtr->inDataPtr);
  82.         if (echoArgsPtr->inDataPtr == (Address)NIL) {
  83.         Vm_MakeUnaccessible((Address) echoArgsPtr, argSize);
  84.         return(RPC_INVALID_ARG);
  85.         }
  86.         Vm_MakeAccessible(VM_OVERWRITE_ACCESS,
  87.                   echoArgsPtr->size, echoArgsPtr->outDataPtr,
  88.                   &outSize, &echoArgsPtr->outDataPtr);
  89.         if (echoArgsPtr->outDataPtr == (Address)NIL) {
  90.         Vm_MakeUnaccessible(echoArgsPtr->inDataPtr, inSize);
  91.         Vm_MakeUnaccessible((Address) echoArgsPtr, argSize);
  92.         return(RPC_INVALID_ARG);
  93.         }
  94.         echoArgsPtr->size = (inSize > outSize) ? outSize : inSize ;
  95.  
  96.         status = Rpc_EchoTest(echoArgsPtr->serverID, echoArgsPtr->n,
  97.                 echoArgsPtr->size, echoArgsPtr->inDataPtr,
  98.                 echoArgsPtr->outDataPtr, &deltaTime);
  99.  
  100.         (void) Vm_CopyOut(sizeof(Time), (Address)&deltaTime,
  101.                      (Address)echoArgsPtr->deltaTimePtr);
  102.         Vm_MakeUnaccessible(echoArgsPtr->inDataPtr, inSize);
  103.         Vm_MakeUnaccessible(echoArgsPtr->outDataPtr, outSize);
  104.         Vm_MakeUnaccessible((Address) echoArgsPtr, argSize);
  105.         break;
  106.     }
  107.     case TEST_RPC_SEND: {
  108.         Rpc_EchoArgs *echoArgsPtr = (Rpc_EchoArgs *)argPtr;
  109.         Time deltaTime;
  110.  
  111.         Vm_MakeAccessible(VM_READONLY_ACCESS, sizeof(Rpc_EchoArgs),
  112.                (Address) echoArgsPtr, &argSize,
  113.                (Address *) (&echoArgsPtr));
  114.         if (argSize != sizeof(Rpc_EchoArgs)) {
  115.         return(RPC_INVALID_ARG);
  116.         }
  117.         Vm_MakeAccessible(VM_READONLY_ACCESS,
  118.                   echoArgsPtr->size, echoArgsPtr->inDataPtr,
  119.                   &inSize, &echoArgsPtr->inDataPtr);
  120.         if (echoArgsPtr->inDataPtr == (Address)NIL) {
  121.         Vm_MakeUnaccessible((Address) echoArgsPtr, argSize);
  122.         return(RPC_INVALID_ARG);
  123.         }
  124.  
  125.         status = Rpc_SendTest(echoArgsPtr->serverID, echoArgsPtr->n,
  126.                 inSize, echoArgsPtr->inDataPtr, &deltaTime);
  127.  
  128.         (void) Vm_CopyOut(sizeof(Time), (Address)&deltaTime,
  129.                      (Address)echoArgsPtr->deltaTimePtr);
  130.         Vm_MakeUnaccessible(echoArgsPtr->inDataPtr, inSize);
  131.         Vm_MakeUnaccessible((Address) echoArgsPtr, argSize);
  132.         break;
  133.     }
  134.     default:
  135.         status = RPC_INVALID_ARG;
  136.         break;
  137.     }
  138.     return(status);
  139. }
  140.  
  141.  
  142. /*
  143.  *----------------------------------------------------------------------
  144.  *
  145.  * Rpc_GetStats --
  146.  *
  147.  *    Copy out rpc system stats.
  148.  *
  149.  * Results:
  150.  *    SUCCESS, unless an argument could not be made accessible.
  151.  *
  152.  * Side effects:
  153.  *    Fill in the requested statistics.
  154.  *
  155.  *----------------------------------------------------------------------
  156.  */
  157. ReturnStatus
  158. Rpc_GetStats(command, option, argPtr)
  159.     int command;        /* Specifies what to do */
  160.     int option;            /* Modifier for command */
  161.     Address argPtr;        /* Argument for command */
  162. {
  163.     ReturnStatus status = SUCCESS;
  164.     
  165.     switch(command) {
  166.     case SYS_RPC_ENABLE_SERVICE: {
  167.         /*
  168.          * A basic On/Off switch for the RPC system.  Servers in
  169.          * particular want to get everything ready before responding
  170.          * to clients.
  171.          */
  172.         if (option) {
  173.         if (recov_Transparent) {
  174.             Fsrecov_ProcessLog();
  175.             Fsrecov_SetupHandles();
  176.         }
  177.         if (rpcSendNegAcks) {
  178.             RpcSetNackBufs();
  179.         }
  180.         printf("Starting RPC service\n");
  181.         rpcServiceEnabled = TRUE;
  182.         } else {
  183.         printf("Warning: Disabling RPC service\n");
  184.         rpcServiceEnabled = FALSE;
  185.         }
  186.         break;
  187.     }
  188.     case SYS_RPC_NUM_NACK_BUFS: {
  189.         /*
  190.          * Set the number of negative ack buffers.
  191.          */
  192.         if (rpcServiceEnabled) {
  193.         printf(
  194.             "Rpc service already enabled, cannot change nack bufs.\n");
  195.         break;
  196.         }
  197.         if (option > 0) {
  198.         printf("Setting number of nack bufs to %d\n", option);
  199.         rpc_NumNackBuffers = option;
  200.         RpcSetNackBufs();
  201.         }
  202.         break;
  203.     }
  204.     case SYS_RPC_SET_MAX: {
  205.         /*
  206.          * Set the maximum number of server procs allowed.  This can't
  207.          * go higher than the absolute maximum.
  208.          */
  209.         if (option <= 0) {
  210.         printf("Warning: asked to set max number of rpc server ");
  211.         printf("procs to %d.  I won't do this.\n", option);
  212.         } if (option < rpcNumServers) {
  213.         printf("Warning: asked to set max number of rpc server ");
  214.         printf("procs to %d which is less than the current ", option);
  215.         printf("number of procs: %d.\n", rpcNumServers);
  216.         printf("I can't do this.\n");
  217.         } else if (option > rpcAbsoluteMaxServers) {
  218.         printf("Warning: asked to set max number of rpc server ");
  219.         printf("procs to %d which is above the absolute ", option);
  220.         printf("maximum of %d.\n", rpcAbsoluteMaxServers);
  221.         printf("Setting this to maximum instead.\n");
  222.         rpcMaxServers = rpcAbsoluteMaxServers;
  223.         } else {
  224.         printf("Setting max number of server procs to %d.\n", option);
  225.         rpcMaxServers = option;
  226.         }
  227.         break;
  228.     }
  229.     case SYS_RPC_SET_NUM: {
  230.         /*
  231.          * Set the number of rpc processes to the given number, if
  232.          * there aren't already that many.
  233.          */
  234.         int    pid;
  235.  
  236.         if (option <= 0) {
  237.         printf("Warning: asked to set number of rpc server ");
  238.         printf("procs to %d.  I won't do this.\n", option);
  239.         } else if (option < rpcNumServers) {
  240.         printf("There are already %d server procs, ", rpcNumServers);
  241.         printf("and I won't kill them.\n");
  242.         } else if (option > rpcMaxServers) {
  243.         printf("Warning: asked to set number of rpc server ");
  244.         printf("procs to %d, which is above the maximum of %d\n",
  245.             option, rpcMaxServers);
  246.         printf("I'll create up to the maximum.\n");
  247.         while (rpcNumServers < rpcMaxServers) {
  248.             if (Rpc_CreateServer(&pid) == SUCCESS) {
  249.             printf("RPC srvr %x\n", pid);
  250.             RpcResetNoServers(0);
  251.             } else {
  252.             printf("Warning: no more RPC servers\n");
  253.             RpcResetNoServers(-1);
  254.             }
  255.         }
  256.         } else {
  257.         /* create the correct number */
  258.         while (rpcNumServers < option) {
  259.             if (Rpc_CreateServer(&pid) == SUCCESS) {
  260.             printf("RPC srvr %x\n", pid);
  261.             RpcResetNoServers(0);
  262.             } else {
  263.             printf("Warning: no more RPC servers\n");
  264.             RpcResetNoServers(-1);
  265.             }
  266.         }
  267.         }
  268.         break;
  269.     }
  270.     case SYS_RPC_NEG_ACKS: {
  271.         printf("Turning negative acknowledgements %s.\n",
  272.             option ? "on" : "off");
  273.         rpcSendNegAcks = option;
  274.         break;
  275.     }
  276.     case SYS_RPC_CHANNEL_NEG_ACKS: {
  277.         printf("Turning client policy of ramping down channels %s.\n",
  278.             option ? "on" : "off");
  279.         rpcChannelNegAcks = option;
  280.         break;
  281.     }
  282.     case SYS_RPC_CLT_STATS: {
  283.         register Rpc_CltStat *cltStatPtr;
  284.  
  285.         cltStatPtr = (Rpc_CltStat *)argPtr;
  286.         if (cltStatPtr == (Rpc_CltStat *)NIL ||
  287.         cltStatPtr == (Rpc_CltStat *)0 ||
  288.         cltStatPtr == (Rpc_CltStat *)USER_NIL) {
  289.         
  290.         Rpc_PrintCltStat();
  291.         } else {
  292.         RpcResetCltStat();
  293.         status = Vm_CopyOut(sizeof(Rpc_CltStat),
  294.                   (Address)&rpcTotalCltStat,
  295.                   (Address) cltStatPtr);
  296.         }
  297.         break;
  298.     }
  299.     case SYS_RPC_SRV_STATS: {
  300.         register Rpc_SrvStat *srvStatPtr;
  301.  
  302.         srvStatPtr = (Rpc_SrvStat *)argPtr;
  303.         if (srvStatPtr == (Rpc_SrvStat *)NIL ||
  304.         srvStatPtr == (Rpc_SrvStat *)0 ||
  305.         srvStatPtr == (Rpc_SrvStat *)USER_NIL) {
  306.         
  307.         Rpc_PrintSrvStat();
  308.         } else {
  309.         RpcResetSrvStat();
  310.         status = Vm_CopyOut(sizeof(Rpc_SrvStat),
  311.                   (Address)&rpcTotalSrvStat,
  312.                   (Address) srvStatPtr);
  313.         }
  314.         break;
  315.     }
  316.     case SYS_RPC_TRACE_STATS: {
  317.         switch(option) {
  318.         case SYS_RPC_TRACING_PRINT:
  319.             Rpc_PrintTrace((ClientData)32);
  320.             break;
  321.         case SYS_RPC_TRACING_ON:
  322.             rpc_Tracing = TRUE;
  323.             break;
  324.         case SYS_RPC_TRACING_OFF:
  325.             rpc_Tracing = FALSE;
  326.             break;
  327.         default:
  328.             /*
  329.              * The option is the size of the users buffer to
  330.              * hold all the trace records.
  331.              */
  332.             status = Trace_Dump(rpcTraceHdrPtr, RPC_TRACE_LEN, argPtr);
  333.             break;
  334.         }
  335.         break;
  336.     }
  337.     case SYS_RPC_SERVER_HIST: {
  338.         /*
  339.          * Operate on the service-time histograms, depending on option.
  340.          */
  341.         if (option > 0 && option <= RPC_LAST_COMMAND) {
  342.         /*
  343.          * Copy out the histogram for the service time of the RPC
  344.          * indicated by option.
  345.          */
  346.         status = Rpc_HistDump(rpcServiceTime[option], argPtr);
  347.         } else if (option > RPC_LAST_COMMAND) {
  348.         status = RPC_INVALID_ARG;
  349.         } else {
  350.         /*
  351.          * Reset all the server side histograms
  352.          */
  353.         status = SUCCESS;
  354.         for (option = 1 ; option <= RPC_LAST_COMMAND ; option++) {
  355.             Rpc_HistReset(rpcServiceTime[option]);
  356.         }
  357.         }
  358.         break;
  359.     }
  360.     case SYS_RPC_CLIENT_HIST: {
  361.         /*
  362.          * Operate on the client call-time histograms, depending on option.
  363.          */
  364.         if (option > 0 && option <= RPC_LAST_COMMAND) {
  365.         /*
  366.          * Copy out the histogram for the client's view of the service
  367.          * time of the RPC indicated by option.
  368.          */
  369.         status = Rpc_HistDump(rpcCallTime[option], argPtr);
  370.         } else if (option > RPC_LAST_COMMAND) {
  371.         status = RPC_INVALID_ARG;
  372.         } else {
  373.         /*
  374.          * Reset all the client side histograms
  375.          */
  376.         status = SUCCESS;
  377.         for (option = 1 ; option <= RPC_LAST_COMMAND ; option++) {
  378.             Rpc_HistReset(rpcCallTime[option]);
  379.         }
  380.         }
  381.         break;
  382.     }
  383.     case SYS_RPC_SRV_STATE: {
  384.         /*
  385.          * Return the state of the server processes.
  386.          */
  387.         if (option >= 0 && option < rpcNumServers) {
  388.         /*
  389.          * Copy out the state of the option'th server process.
  390.          */
  391.         status = Vm_CopyOut(sizeof(RpcServerState),
  392.                   (Address)rpcServerPtrPtr[option], argPtr);
  393.         } else {
  394.         status = RPC_INVALID_ARG;
  395.         }
  396.         break;
  397.     }
  398.     case SYS_RPC_CLT_STATE: {
  399.         /*
  400.          * Return the state of the client channels.
  401.          */
  402.         if (option >= 0 && option < rpcNumChannels) {
  403.         /*
  404.          * Copy out the state of the option'th client channel.
  405.          */
  406.         status = Vm_CopyOut(sizeof(RpcClientChannel),
  407.                   (Address)rpcChannelPtrPtr[option], argPtr);
  408.         } else {
  409.         status = RPC_INVALID_ARG;
  410.         }
  411.         break;
  412.     }
  413.     case SYS_RPC_CALL_COUNTS: {
  414.         register int *callCountPtr;
  415.  
  416.         callCountPtr = (int *)argPtr;
  417.         if (callCountPtr == (int *)NIL ||
  418.         callCountPtr == (int *)0 ||
  419.         callCountPtr == (int *)USER_NIL ||
  420.         option <= 0) {
  421.  
  422.         Rpc_PrintCallCount();
  423.         } else {
  424.         status = Vm_CopyOut(option,
  425.                   (Address) rpcClientCalls,
  426.                   (Address) callCountPtr);
  427.         }
  428.         break;
  429.     }
  430.     case SYS_RPC_SRV_COUNTS: {
  431.         register int *serviceCountPtr;
  432.  
  433.         serviceCountPtr = (int *)argPtr;
  434.         if (serviceCountPtr == (int *)NIL ||
  435.         serviceCountPtr == (int *)0 ||
  436.         serviceCountPtr == (int *)USER_NIL ||
  437.         option <= 0) {
  438.  
  439.         Rpc_PrintServiceCount();
  440.         } else {
  441.         status = Vm_CopyOut(option,
  442.                   (Address) rpcServiceCount,
  443.                   (Address) serviceCountPtr);
  444.         }
  445.         break;
  446.     }
  447.     default:
  448.         status = RPC_INVALID_ARG;
  449.         break;
  450.     }
  451.     return(status);
  452. }
  453.